from PySide2.QtCore import *
import logging
import time
import datetime
import re

class Task_signal(QObject):
    update_next_time = Signal(int,str)
    execute_task = Signal(int)
    update_remaining_count = Signal(int,int)
    update_timer_text = Signal(int,str)
    finished = Signal()

class Task_worker(QObject):

    def __init__(self) -> None:
        super().__init__()
        self.log = logging.getLogger('app_log')
        self.signal = Task_signal()
        self._work_flag = True

        # task_list [
        #   {
        #       'id':xx,
        #       'start_time':xx,
        #       'exec_times':xx,
        #       'loop_day':xx,
        #       'loop_hour':xx
        #   },
        # ]
        self.task_list = []


    def add_task(self,task:dict):
        task['exec_times'] = int (task['exec_times'])
        start_time:datetime
        if task['start_time'] == '':
            start_time = datetime.datetime.now()
        else:
            start_time = datetime.datetime.strptime(task['start_time'],'%Y-%m-%d %H:%M')
        interval_time = datetime.timedelta(days=int(task['loop_day']),hours=int(task['loop_hour']))
        if task['exec_times'] == 0:
            # 更新ui
            str_next_time = '超时'
            self.signal.update_next_time.emit(task['id'],str_next_time)
            self.signal.update_remaining_count.emit(task['id'],0)
            return
        
        #特殊处理
        if task['exec_times'] != 1  and int(task['loop_day']) == 0 and int(task['loop_hour']) == 0:
            str_next_time = '循环周期错误'
            self.signal.update_next_time.emit(task['id'],str_next_time)
            return
        
        if task['exec_times'] == -1:
            reg = '^-.*'
            task['next_time'] = start_time
            str_dff_time = str(task['next_time'] - datetime.datetime.now())
            mat = re.search(reg,str_dff_time)
            
            while(mat):
                task['next_time'] += interval_time
                str_dff_time = str(task['next_time'] - datetime.datetime.now())
                mat = re.search(reg,str_dff_time)
            
            str_next_time = task['next_time'].strftime('%Y-%m-%d %H:%M')
            self.signal.update_next_time.emit(task['id'],str_next_time)

        if task['exec_times'] > 0:
            reg = '^-.*'
            task['next_time'] = start_time + interval_time
            str_time = str(task['next_time'] - datetime.datetime.now())
            mat = re.search(reg,str_time)
            if not mat:
                str_next_time = task['next_time'].strftime('%Y-%m-%d %H:%M')
                self.signal.update_remaining_count.emit(task['id'],task['exec_times'])
                self.signal.update_next_time.emit(task['id'],str_next_time)
            else:
                time_out = True
                remaining_count = task['exec_times']
                for i in range(task['exec_times']-1):
                    remaining_count -= 1
                    task['next_time'] += interval_time
                    str_time = str(task['next_time'] - datetime.datetime.now())
                    mat = re.search(reg,str_time)
                    if not mat:
                        str_next_time = task['next_time'].strftime('%Y-%m-%d %H:%M')
                        self.signal.update_next_time.emit(task['id'],str_next_time)
                        time_out = False
                        self.signal.update_remaining_count.emit(task['id'],remaining_count)
                        break
                if time_out:
                    str_next_time = '超时'
                    self.signal.update_next_time.emit(task['id'],str_next_time)
                    self.signal.update_remaining_count.emit(task['id'],0)
                    return

        # 更新或增加任务
        is_append = True
        for i in range(len(self.task_list)):
            if self.task_list[i]['id'] == task['id']:
                self.task_list[i] = task
                is_append =False
                break
        if is_append:
            self.task_list.append(task)

    def remove_task(self,task_id:int):
        index = -1
        for i in range(len(self.task_list)):
            if self.task_list[i]['id'] == task_id:
                index = i
                break
        if index > -1:
            del self.task_list[index]


    def start_work(self):
        #1 day, 6:36:03.422420
        #73890 days, 6:36:03.422420
        reg_day_time = '^(?P<day>\d+)\s+day\S*,\s+(?P<time>\d+:\d+:\d+).*'
        reg_time = '^(?P<time>\d+:\d+:\d+).*'
        while (self._work_flag):
            del_list = []
            for i in range(len(self.task_list)):
                now_time = datetime.datetime.now()
                difference_time = str(self.task_list[i]['next_time'] - now_time)
                mat_day_time = re.search(reg_day_time,difference_time)
                mat_time = re.search(reg_time,difference_time)
                print(mat_day_time,mat_time)
                if mat_day_time:
                    self.signal.update_timer_text.emit(self.task_list[i]['id'],f'{mat_day_time.group("day")}天 {mat_day_time.group("time")}')
                elif mat_time:
                    self.signal.update_timer_text.emit(self.task_list[i]['id'],f'{mat_time.group("time")}')
                else:
                    # 发送信号 执行任务
                    self.signal.execute_task.emit(self.task_list[i]['id'])
                    # 移除任务
                    del_list.append(i)
                    self.signal.update_timer_text.emit(self.task_list[i]['id'],'')

            for i in del_list:
                del self.task_list[i]

            time.sleep(1)  

        self.signal.finished.emit()

    def stop_work(self):
        self._work_flag = False
    

    def clear_work(self):
        self.task_list.clear()
